﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;

using Blog.Net.Business.BusinessObjects;
using Blog.Net.Common.DataObjects;
using Blog.Net.DataAccess.DataControls;

namespace Blog.Net.Controls
{
    /// <summary>
    /// Blog Entry Rating Control
    /// </summary>
    [DefaultProperty("EntryId")]
    public class Rating : System.Web.UI.WebControls.WebControl, INamingContainer
    {
        /// <summary>
        /// Gets or sets the entry id.
        /// </summary>
        /// <value>The entry id.</value>
        [Description("The Id of the Blog Entry")]
        public int? EntryId
        {
            get
            {
                if (ViewState["EntryId"] == null)
                    ViewState["EntryId"] = -1;

                return (int?)ViewState["EntryId"];
            }
            set
            {
                ViewState["EntryId"] = value;
                blogEntry = BlogEntryDataControl.Instance.GetById(value);
            }
        }

        private List<ImageButton> buttons = new List<ImageButton>();

        /// <summary>
        /// Gets or sets the blog entry.
        /// </summary>
        /// <value>The blog entry.</value>
        private BlogEntryBO blogEntry
        {
            get
            {
                return new BlogEntryBO((BlogEntry)ViewState["blogEntry"]);
            }
            set
            {
                ViewState["blogEntry"] = value.POCO;
            }
        }

        #region Methods

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            Panel ratePanel = new Panel();

            ImageButton rateOne = new ImageButton();
            rateOne.ID = "rateOne";
            rateOne.SkinID = getImageName(rateOne);
            rateOne.Click += new ImageClickEventHandler(rateBtn_Click);
            ratePanel.Controls.Add(rateOne);

            ImageButton rateTwo = new ImageButton();
            rateTwo.ID = "rateTwo";
            rateTwo.SkinID = getImageName(rateTwo);
            rateTwo.Click += new ImageClickEventHandler(rateBtn_Click);
            ratePanel.Controls.Add(rateTwo);

            ImageButton rateThree = new ImageButton();
            rateThree.ID = "rateThree";
            rateThree.SkinID = getImageName(rateThree);
            rateThree.Click += new ImageClickEventHandler(rateBtn_Click);
            ratePanel.Controls.Add(rateThree);

            ImageButton rateFour = new ImageButton();
            rateFour.ID = "rateFour";
            rateFour.SkinID = getImageName(rateFour);
            rateFour.Click += new ImageClickEventHandler(rateBtn_Click);
            ratePanel.Controls.Add(rateFour);

            ImageButton rateFive = new ImageButton();
            rateFive.ID = "rateFive";
            rateFive.SkinID = getImageName(rateFive);
            rateFive.Click += new ImageClickEventHandler(rateBtn_Click);
            ratePanel.Controls.Add(rateFive);

            Literal rateLit = new Literal();
            rateLit.Text = "&nbsp;";
            ratePanel.Controls.Add(rateLit);

            Label rateLbl = new Label();
            rateLbl.ID = "rateLbl";
            rateLbl.Text = string.Format("( {0:0.0} / {1} )", blogEntry.Rating, blogEntry.Votes);
            rateLbl.Style.Add("vertical-align", "top");
            ratePanel.Controls.Add(rateLbl);

            this.Controls.Add(ratePanel);
        }

        /// <summary>
        /// Called when [bubble event].
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        /// <returns></returns>
        protected override bool OnBubbleEvent(object source, EventArgs e)
        {
            bool handled = false;

            if (e is ImageClickEventArgs)
            {
                ImageClickEventArgs ice = (ImageClickEventArgs)e;
                rateBtn_Click(source, ice);
                handled = true;
            }
            return handled;
        }


        /// <summary>
        /// Handles the Click event of the rateOne control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.ImageClickEventArgs"/> instance containing the event data.</param>
        protected void rateBtn_Click(object sender, ImageClickEventArgs e)
        {
            ImageButton rateBtn = (ImageButton)sender;
            switch (rateBtn.ID)
            {
                case "rateOne":
                    blogEntry.Points += 1;
                    break;
                case "rateTwo":
                    blogEntry.Points += 2;
                    break;
                case "rateThree":
                    blogEntry.Points += 3;
                    break;
                case "rateFour":
                    blogEntry.Points += 4;
                    break;
                case "rateFive":
                    blogEntry.Points += 5;
                    break;
            }

            blogEntry.Votes += 1;
            BlogEntryDataControl.Instance.Save(blogEntry);

            this.Controls.Clear();

            CreateChildControls();
        }

        /// <summary>
        /// Gets the name of the image.
        /// </summary>
        /// <param name="ctlName">Name of the CTL.</param>
        /// <param name="rating">The rating.</param>
        /// <returns></returns>
        private string getImageName(ImageButton ctl)
        {
            switch (ctl.ID)
            {
                case "rateOne":
                    if (blogEntry.Rating > .5)
                        return rate.full;
                    if (blogEntry.Rating > 0)
                        return rate.half;
                    else
                        return rate.none;
                case "rateTwo":
                    if (blogEntry.Rating > 1.5)
                        return rate.full;
                    if (blogEntry.Rating > 1)
                        return rate.half;
                    else
                        return rate.none;
                case "rateThree":
                    if (blogEntry.Rating > 2.5)
                        return rate.full;
                    if (blogEntry.Rating > 2)
                        return rate.half;
                    else
                        return rate.none;
                case "rateFour":
                    if (blogEntry.Rating > 3.5)
                        return rate.full;
                    if (blogEntry.Rating > 3)
                        return rate.half;
                    else
                        return rate.none;
                case "rateFive":
                    if (blogEntry.Rating > 4.5)
                        return rate.full;
                    if (blogEntry.Rating > 4)
                        return rate.half;
                    else
                        return rate.none;
            }
            return "rate_none";
        }

        #endregion

        /// <summary>
        /// Rate string enumeration
        /// </summary>
        private sealed class rate
        {
            public static string full = "rate_full";
            public static string half = "rate_half";
            public static string none = "rate_none";
        }
    }
}

